// Base.h: Nan Dun

#ifndef BASE_H
#define BASE_H

#include <iostream>
#include <string>
using namespace std;

class Base {
public:
	Base();					// constructor
	Base(string);			// constructor overloading
	Base(int);	// initialize list		
	Base(string, int);
	~Base();				// Destructor

	static int N;			// static variable
	static int getN(void);	// static function
	
	void set(string);		// Method overloading
	void set(int);
	void set(string, int);
    void setToken(int);
	string getName(void) const;
	int getId(void) const;
    int getToken(void) const;
	void print(void);
  
  	// Q: Change to const and modify to make it work
	Base operator+(Base&);			// operator overloading
	Base operator-(Base&);
    Base operator*(const Base&);         // * definition
    Base operator/(Base&);
	Base& operator=(const Base&);

	friend void friendPrint(Base&);	// friend function
	friend class BaseFriend;
	friend ostream& operator<<(ostream&, const Base&);
	
	virtual void printSelf(void) { return; };

protected:
	string *name;
	int id;

private:
	int base_token;
};

class BaseFriend {
public:
	void printOther(Base&);
};

class AbstractBase {
public:
	virtual void printSelf(void) = 0;
};

//void friendPrint(Base&);	// Q: What happens if commenting this line?
ostream& operator<<(ostream&, const Base&);

#endif	// BASE_H
